1 module hip.api.filesystem.hipfs;
2 
3 ///Less dependencies
4 enum : ubyte
5 {
6     /// Offset is relative to the beginning
7     SEEK_SET,
8     /// Offset is relative to the current position
9     SEEK_CUR,
10     /// Offset is relative to the end
11     SEEK_END
12 }
13 
14 enum FileMode : ubyte
15 {
16     READ,
17     WRITE,
18     APPEND,
19     READ_WRITE,
20     READ_APPEND
21 }
22 
23 /**
24  * Result used for memory management after delegate is executed.
25  * The result is free if and only if every delegates returns that it should free the result.
26  */
27 enum FileReadResult : bool
28 {
29     ///Don't do anything.
30     keep = false,
31     ///Frees the file data
32     free = true,
33 }
34 
35 ///Unused yet, but planned
36 interface IHipDirectoryItf
37 {
38     bool open();
39     bool close();
40     string[] getFileNames();
41     size_t count();
42     int opApply(scope int delegate(in string fileName) dg);
43 }
44 
45 interface IHipFileItf
46 {
47     bool open(string path, FileMode mode);
48     int read(void* buffer, ulong count);
49     ///Whence is the same from stdio
50     int seek(long count, int whence);
51     ulong getSize();
52     void close();
53 }
54 interface IHipFSPromise
55 {
56     /**
57      *
58      * Params:
59      *   onSuccess = A delegate containing the file data as an input
60      * Returns:The promise itself
61      */
62     IHipFSPromise addOnSuccess(FileReadResult delegate(in ubyte[] data) onSuccess);
63     IHipFSPromise addOnError(void delegate(string error) onError);
64     bool resolved() const;
65     void dispose();
66 }
67 
68 interface IHipFileSystemInteraction
69 {
70     protected final const(wchar*) cachedWStringz(wstring path)
71     {
72         __gshared wchar[] cache;
73         if(path.length > cache.length)
74             cache.length = path.length + 1;
75         cache[0..path.length] = path[];
76         cache[path.length] = '\0';
77 
78         return cache.ptr;
79     }
80 
81     protected final const(char*) cachedStringz(string path)
82     {
83         __gshared char[] cache;
84         if(path.length > cache.length)
85             cache.length = path.length + 1;
86         cache[0..path.length] = path[];
87         cache[path.length] = '\0';
88 
89         return cache.ptr;
90     }
91 
92     /**
93     *   onSuccess: Maybe be executed before the function returns (on sync platforms).
94     *
95     *   onError: Error is reserved for when the file exists but can't be read.
96     Not being able to read because it doesn't exists is not an error. 
97     *   
98     *
99     *   Returns:
100     *       - Sync Platforms: File does not exists, can't read.
101     *       - Async platforms: File does not exists
102     */
103     bool read(string path, FileReadResult delegate(ubyte[] data) onSuccess, void delegate(string err = "Corrupted File") onError);
104     bool write(string path, const(void)[] data);
105     bool exists(string path);
106     bool remove(string path);
107 
108     bool isDir(string path);
109     final bool isFile(string path){return !isDir(path);}
110 }
111 
112 /** 
113  * Provides the interface for the filesystem singleton
114  */
115 interface IHipFS
116 {
117     ///Gets a path from the installed path
118     string getPath(string path);
119 
120     ///Uses the only extra verifications to check if the path is valid
121     bool isPathValidExtra(string path);
122 
123     /** 
124      * Does some default validations in the path then it executes the extra ones.
125      * Params:
126      *   path = The path to validate
127      *   expectsFile = Checks whether that path is a file or a directory.
128      *   shouldVerify = Flags for executing extra validations
129      * Returns: Whether the path is valid
130      */
131     bool isPathValid(string path, bool expectsFile = true, bool shouldVerify = true);
132 
133     /** 
134      * Sets the initial path. It can't be a path with higher access than install path.
135      * You may reset it to the install path by using `setPath("")`
136      * Params:
137      *   path = The path to set as base
138      * Returns: If it is a valid path
139      */
140     bool setPath(string path);
141 
142     /** 
143      * Encapsulates both the sync and async in the same API for reading a file
144      * Params:
145      *   path = The path to read
146      * Returns: A task/promise which will output the file data. It returns null if the path is invalid
147      */
148     IHipFSPromise read(string path);
149 
150     /** 
151      * Same as .read
152      * Params:
153      *   path = The path to read
154      * Returns: A task/promise which will output the text data
155      */
156     IHipFSPromise readText(string path);
157     
158     /** 
159      * Currently there is no way to know if the writing has finished. Uses the sync API.
160      * Params:
161      *   path = The path to write
162      *   data = The data to write
163      * Returns: If it was possible to write. May return false if path is invalid.
164      */
165     bool write(string path, const(void)[] data);
166 
167     /** 
168      * Currently it is a sync operation.
169      * Params:
170      *   path = Path to check
171      * Returns: If it exists
172      */
173     bool exists(string path);
174 
175     /** 
176      * Removes from the current path
177      * Params:
178      *   path = The path to remove
179      * Returns: Whether the operation has succeeded
180      */
181     bool remove(string path);
182 
183     /** 
184      * Returns: The current working directory, form the last setPath() call.
185      */
186     string getcwd();
187 
188     /** 
189      * Same as exists. But doesn't use install path. Limited and sync.
190      */
191     bool absoluteExists(string path);
192     /** 
193      * Same as isDir. But doesn't use install path. Limited and sync.
194      */
195     bool absoluteIsDir(string path);
196     /** 
197      * Same as isFile. But doesn't use install path. Limited and sync.
198      */
199     bool absoluteIsFile(string path);
200     /** 
201      * Same as remove. But doesn't use install path. Limited and sync.
202      */
203     bool absoluteRemove(string path);
204     /** 
205      * Same as write. But doesn't use install path. Limited and sync.
206      */
207     bool absoluteWrite(string path, const(void)[] data);
208     /** 
209      * Same as read. But doesn't use install path. Limited and sync.
210      */
211     bool absoluteRead(string path, out void[] output);
212     bool absoluteRead(string path, out ubyte[] output);
213     /** 
214      * Same as readText. But doesn't use install path. Limited and sync.
215      */
216     bool absoluteReadText(string path, out string output);
217     /** 
218      * Checks whether the path is a file
219      */
220     bool isFile(string path);
221     /** 
222      * Checks whether the path is a directory
223      */
224     bool isDir(string path);
225     /** 
226      * Uses a key/value pair for writing cache values. 
227      */
228     string writeCache(string cacheName, void[] data);
229 }
230 
231 ///Dependency injection interface for HipFS
232 private __gshared IHipFS _fs;
233 void setIHipFS(IHipFS fsInstance)
234 {
235     _fs = fsInstance;
236 }
237 IHipFS HipFileSystem()
238 {
239     return _fs;
240 }
241 alias HipFS = .HipFileSystem;